package com.pinoc.demo.randomlottery;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.RandomUtil;
import com.pinoc.design_pattern.visitor.Item;

/**
 * @author pinoc
 * @date 2023/11/13
 */
public class RandomLottery2 {
	/**
	 * 自定义抽奖
	 * 
	 * @param prizePool
	 *            抽奖奖池
	 * @param customThreshold
	 *            控制整体中奖概率
	 * @return 中奖奖品
	 */
	public Prize prizeLottery(final List<Prize> prizePool, Integer customThreshold) {
		List<Integer> weightNodeList = new ArrayList<>(Collections.singletonList(0));
		// 组装权重区间,去除库存为0的奖品
		List<Long> emptyPrize = prizePool.stream().filter(item -> item.getWeight() <= 0).map(Prize::getId).collect(Collectors.toList());
		final List<Prize> weightPrizePool = new ArrayList<>(prizePool);
		// 去除掉剩余库存为空的奖品
		List<Prize> prizePoolList = weightPrizePool.stream().filter(item -> !emptyPrize.contains(item.getId())).collect(Collectors.toList());
		if (CollectionUtil.isEmpty(prizePoolList)) {
			// 奖品已经抽完
			return null;
		}
		for (Prize prize : prizePoolList) {
			weightNodeList.add(weightNodeList.get(weightNodeList.size() - 1) + prize.getWeight());
		}
		int randomInt = customThreshold != null ? RandomUtil.randomInt(0, 100) : RandomUtil.randomInt(0, weightNodeList.get(weightNodeList.size() - 1));
		if (customThreshold != null && randomInt > customThreshold) {
			// 未中奖
			return null;
		}
		// 如果中奖 确定中的哪个奖品
		randomInt = customThreshold != null ? RandomUtil.randomInt(0, weightNodeList.get(weightNodeList.size() - 1)) : randomInt;
		for (int i = 1; i < weightNodeList.size(); i++) {
			Integer endWeight = weightNodeList.get(i);
			Integer startWeight = weightNodeList.get(i - 1);
			if (randomInt >= startWeight && randomInt < endWeight) {
				// 中奖
				Prize prize = prizePoolList.get(i - 1);
				prize.setWeight(prize.getWeight() - 1);
				return prize;
			}
		}
		throw new RuntimeException("程序随机数异常");
	}

	public static void main(String[] args) {
		List<Prize> prizeList = new ArrayList<>();
		prizeList.add(new Prize(0L, "奖品-0", 300));
		prizeList.add(new Prize(1L, "奖品-1", 70));
		prizeList.add(new Prize(2L, "奖品-2", 30));
		prizeList.add(new Prize(3L, "奖品-3", 20));
		prizeList.add(new Prize(4L, "奖品-4", 2));
		RandomLottery2 randomLottery = new RandomLottery2();
		List<Prize> lotteryResult = new ArrayList<>();
		for (int i = 0; i <= 1000; i++) {
			Prize prize;
			if ((prize = randomLottery.prizeLottery(prizeList, 20)) != null) {
				lotteryResult.add(prize);
			}
		}
		Map<String, List<Prize>> collect = lotteryResult.stream().collect(Collectors.groupingBy(Prize::getName));
		collect.forEach((k, v) -> System.out.println(k + " 被抽中 " + v.size() + " 次"));
		System.out.println("一共中奖 " + lotteryResult.size() + " 次");
		System.out.println();
		for (Prize prize : prizeList) {
			System.out.println(prize.getName() + "剩余" + prize.getWeight());
		}
	}
}
